from typing import Callable, Any, Optional
from .json_utils import json_dumps
from .content import ContentProcessor
from .logger import get_default_logger


async def reply(send: Callable, content: Any, status: int = 200, headers: Optional[dict] = None):
    """发送响应 - 使用ContentProcessor消除重复逻辑"""
    try:
        # 使用统一内容处理器 - 消除重复的内容类型检测
        headers = ContentProcessor.prepare_headers(content, headers)
        body = ContentProcessor.process_content(content)
        
        # 确保body是bytes类型
        if not isinstance(body, bytes):
            logger = get_default_logger()
            logger.warn(
                "响应体类型自动转换为bytes",
                event="response_body_type_conversion",
                original_type=type(body).__name__,
                body_preview=str(body)[:100] if len(str(body)) > 100 else str(body)
            )
            body = str(body).encode('utf-8')
        
        # 确保headers符合ASGI规范：字节对列表
        header_pairs = []
        for k, v in headers.items():
            try:
                header_pairs.append((k.encode('utf-8'), v.encode('utf-8')))
            except Exception as e:
                # 如果编码失败，跳过这个header
                logger = get_default_logger()
                logger.warn(
                    "响应头编码失败，跳过此头部",
                    event="response_header_encoding_failed",
                    header_name=k,
                    header_value=str(v)[:50] if v else "",
                    encoding_error=str(e)
                )
        
        # 发送http.response.start消息
        await send({
            "type": "http.response.start",
            "status": status,
            "headers": header_pairs
        })
        
        # 发送http.response.body消息
        await send({"type": "http.response.body", "body": body, "more_body": False})
        
    except Exception as e:
        logger = get_default_logger()
        logger.error(
            "发送响应失败，尝试发送错误响应",
            event="response_send_failed",
            error=str(e),
            error_type=type(e).__name__
        )
        # 尝试发送最简单的错误响应
        try:
            await send({
                "type": "http.response.start",
                "status": 500,
                "headers": [(b"content-type", b"text/plain")]
            })
            await send({
                "type": "http.response.body",
                "body": b"Internal Server Error",
                "more_body": False
            })
        except Exception as e2:
            logger.error(
                "错误响应发送也失败，用户将看到连接错误",
                event="error_response_send_failed",
                primary_error=str(e),
                fallback_error=str(e2),
                user_impact="用户将看到连接中断或超时错误"
            )


# 便捷函数 - 提高可读性
async def send_error(send: Callable, message: str, status: int = 400):
    """发送错误响应"""
    await reply(send, {"error": message}, status)


async def json(send: Callable, data: Any, status: int = 200):
    """发送JSON响应"""
    await reply(send, data, status)


async def html(send: Callable, content: str, status: int = 200):
    """发送HTML响应"""
    await reply(send, content, status)


# WebSocket专用
async def ws_text(send: Callable, action: str, data: str = ""):
    """WebSocket操作 - 明确的字符串参数"""
    if action == "accept":
        await send({"type": "websocket.accept"})
    elif action == "ping":
        await send({"type": "websocket.ping"})
    elif action == "send":
        await send({"type": "websocket.send", "text": data})


# 便捷函数 - 明确的JSON序列化
async def ws_json(send: Callable, data):
    """WebSocket发送JSON数据 - 明确序列化"""
    await ws_text(send, "send", json_dumps(data))